include(['shapes.Hex', 'materials.Material', 'Node'], 
		
function(){
	
	declare('HexGrid');
	
	HexGrid = function(x, y, MAX_COLUMNS, MAX_ROWS){
		this.down = false;
		this.start = {x:0, y:0};
		this.active = 0;
		this.activeNode = null;
		this.node = new Node();
		this.cells = this.node.children;
		this.children = this.cells;
		this.current = {x:0,y:0,col:0,row:0};
		this.MAX_COLUMNS = MAX_COLUMNS || 40;
		this.MAX_ROWS    = MAX_ROWS || 40;
		
		this.activeCells = [];
		
		this.templateCell = Hex.createCell(0,0);
		this.widthRatio   = 1/(this.templateCell.width);
		this.heightRatio  = 1/this.templateCell.height;
		
		this.selectedMaterial = Material.create({name:'HexSelection', stroke:true, strokeStyle:'black'})
		this.debugTextMaterial = Material.create({name:'Debug', stroke:true, lineWidth:1, strokeStyle:'green'})
		
		for(var row=0; row < this.MAX_ROWS; row++ ){
			for(var col=0; col < this.MAX_COLUMNS; col++ ){
				var cell = Hex.createCell(col,row);
				cell.row = row;
				cell.col = col*2;
				cell.x = cell.meshData()[0].x;
				cell.y = cell.meshData()[1].y;
				cell.owner = this;
                cell.toLocalCoordinates = function(_x, _y){
                    return this.owner.node.toLocalCoordinates({x:_x ,y:_y});
                };
                cell.toWorldCoordinate = function(_x, _y){
                    return this.owner.node.toWorldCoordinates({x:_x ,y:_y});
                };
				if( (row % 2 ) != 0 ){
					cell.col = cell.col+1;
				}	
				this.cells[""+row+","+cell.col] = cell;
			}
		}
		this._offsetX = x || 0;
		this._offsetY = y || 0;
		this.translate(this._offsetX, this._offsetY);
	};
	HexGrid.prototype = {
		render : function(gw){
			var c = gw.c;
			if( this.active ){
				var cell = this.cells[""+this.current.row+","+this.current.col];
				
				var m = this.node.material;
				this.node.material = this.selectedMaterial;
				this.node.renderChild(gw, cell);
				this.node.material = m;
				
				c.beginPath();
				
				c.fillStyle = "green";
				var p = {x:this.current.x, y:this.current.y};
				this.node.matrix2d.apply(p, p);
				c.fillText( "cell : row=" + this.current.row + " col=" + this.current.col + ", x=" + this.current.x + ", y=" + this.current.y , p.x, p.y);
				c.stroke();
			}
		},
		hit : function(e){
			var x = e.x;
			var y = e.y;
			
			var cell = this.getCell(x,y);
			if(cell){
				this.select(cell);			
			}else{
				this.active = false;
			}
		},
		select : function( cell ){
			this.current.col = cell.col;
			this.current.row = cell.row;
			this.current.x = cell.x;
			this.current.y = cell.y;
			this.active = true;
		},	
		guess : function(x,y){
			var p = {x:x, y:y}
			p = this.node.toLocalCoordinates(p);
			var column = Math.floor(p.x * this.widthRatio);
			var row    = Math.floor(p.y * this.heightRatio);
			if( (row%2) != 0 ){
				if((column%2) !=0)
					column--
			}else if( row%2 == 0){
				if( column%2 == 0 )
					column--
			}		
			return {column:column--, row:row};
		},
		determinedFind : function(x,y){
			var c = 0;
			if( c ) c--;
			for(; c < this.MAX_COLUMNS; c++){
				var r = 0;
				if( r ) r--;
				for(; r < this.MAX_ROWS; r++){
					var cell = this.cells[""+r+","+c]; 
					if( this.node.intersectsChild({x:x, y:y}, cell)){
						return cell;
					}
				}
			}
			return null;		
		},
		last : {},
		childAt : function(row, col){
			var cols = this.owner.gridMeta.colCount*2;
			var rows = this.owner.gridMeta.rowCount;
			var adjRow = row, adjCol = col;
			var dir = 0;
			var grid = this;
			if( row < 0 ){
				adjRow = rows + row;
				dir = Direction.UP
			}
			if( row >= rows ){
				adjRow = row % rows
				dir = Direction.DOWN
			}
			if( col < 0 ){
				adjCol = cols + col;
				dir = dir | Direction.LEFT
			}
			if( col >= cols ){
				adjCol = col % cols
				dir = dir | Direction.RIGHT
			}
			if( dir ){
				grid = this.owner.getNeighbor(this, dir);
			}			
			var child = grid.children[""+adjRow+","+adjCol];
			return child;
		},
		getCell : function(x, y){
			var loc = this.guess(x,y);
			var last = this.last;
			
			if( last.x != loc.column || last.y != loc.row){
				last.x = loc.column;
				last.y = loc.row;
			}
			
			for(var r=loc.row-2; r <= loc.row+2; r++){
				for(var c=loc.column-2; c <= loc.column+2; c+=2){
					var tc = c;
					if( r % 2 != 0 ^ c % 2 != 0)
						tc++;
					var cell = this.cells[""+r+","+tc];
					if( this.checkHit(cell, x, y)){
						return cell;
					}
				}
			}
			return null;
		},
		getNeighbors : function(cell){
			if( cell.owner != this ) return;
			var row = cell.row;
			var col = cell.col;
			
			var neighbors = [];
			neighbors[Direction.LEFT|Direction.UP] = this.childAt(row-1, col-1);
			neighbors[Direction.UP] = this.childAt(row-2, col);
			neighbors[Direction.RIGHT|Direction.UP] = this.childAt(row-1, col+1);
			neighbors[Direction.RIGHT|Direction.DOWN] = this.childAt(row+1, col+1);
			neighbors[Direction.DOWN] = this.childAt(row+2, col);
			neighbors[Direction.LEFT|Direction.DOWN] = this.childAt(row+1, col-1);
			return neighbors;
		},
		checkHit : function(cell, x, y){
			if( cell ){
				if( this.node.intersectsChild({x:x, y:y}, cell, 1) )
					return cell;
			}
			return false;
		}		
		,release : function(){
			
		}
		,intersects : function(){ return false; }
		,setActive : function(value){}
		,onMove : function( e ){
			if( e.bId ){
				this.hit(e);
			}
		}
		,onButtonDown : function( e ){
			this.hit(e);
		}
		,onButtonUp : function( e ){
			this.release();
		}
		,translate : function(x, y){
			this.node.translate( x, y );
		}
		,setTranslation : function(x, y){
			this.node.setTranslation( x+this._offsetX, y+this._offsetY );
		}
		,boundingBox : function(){
			return this.node.boundingBox();
		}
        ,setParent : function(parent){
            this.node.setParent(parent);
        }
	};
});